/*
 * @Author      : ZhouQiJun
 * @Date        : 2025-09-04 01:05:34
 * @LastEditors : ZhouQiJun
 * @LastEditTime: 2025-09-04 01:06:01
 * @Description : geoJSON 相关函数
 */
import type { PlainObj } from '@ol/types'
import { isNil, isPlainObject, isString } from 'es-toolkit'

export { isGeojsonObj, isGeoJson }

/**
 * 判断一个对象是否为 GeoJSON 对象
 */
function isGeojsonObj(obj: PlainObj): obj is PlainObj {
  if (isNil(obj) || !isPlainObject(obj)) return false

  const geo = obj
  if (typeof geo.type !== 'string') return false

  const type = geo.type

  const geometryTypes = [
    'Point',
    'LineString',
    'Polygon',
    'MultiPoint',
    'MultiLineString',
    'MultiPolygon',
    'GeometryCollection',
  ]

  if (geometryTypes.includes(type)) {
    if (type === 'GeometryCollection') {
      return Array.isArray(geo.geometries)
    }
    return Array.isArray(geo.coordinates)
  }

  if (type === 'Feature') {
    return geo.hasOwnProperty('geometry') && geo.hasOwnProperty('properties')
  }

  if (type === 'FeatureCollection') {
    if (!Array.isArray(geo.features)) return false
    return geo.features.every((f) => isGeojsonObj(f) && (f as PlainObj).type === 'Feature')
  }

  return false
}

function isGeoJson(valString: string) {
  if (!isString(valString) || valString.trim() === '') {
    return false
  }
  // 清除字符串两端的空白，便于判断
  const trimmedString = valString.trim()

  // GeoJSON 必须以 { 开头
  if (trimmedString.startsWith('{')) {
    try {
      // 尝试解析为 JSON，确保格式有效
      const geoObj = JSON.parse(trimmedString)
      // GeoJSON 格式必须包含 "type" 字段
      if (isGeojsonObj(geoObj)) {
        return true
      }
      return false
    } catch (e) {
      // 如果解析失败，说明不是有效的 GeoJSON
      return false
    }
  }
  return false
}
